home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Utilities / BasiliskII / src / ether.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-02  |  5.9 KB  |  184 lines

  1. /*
  2.  *  ether.cpp - Ethernet device driver
  3.  *
  4.  *  Basilisk II (C) 1997-2001 Christian Bauer
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  */
  20.  
  21. /*
  22.  *  SEE ALSO
  23.  *    Inside Macintosh: Devices, chapter 1 "Device Manager"
  24.  *    Inside Macintosh: Networking, chapter 11 "Ethernet, Token Ring, and FDDI"
  25.  *    Inside AppleTalk, chapter 3 "Ethernet and TokenTalk Link Access Protocols"
  26.  */
  27.  
  28. #include <string.h>
  29.  
  30. #include "sysdeps.h"
  31. #include "cpu_emulation.h"
  32. #include "main.h"
  33. #include "macos_util.h"
  34. #include "emul_op.h"
  35. #include "ether.h"
  36. #include "ether_defs.h"
  37.  
  38. #define DEBUG 0
  39. #include "debug.h"
  40.  
  41.  
  42. // Global variables
  43. uint8 ether_addr[6];    // Ethernet address (set by EtherInit())
  44. bool net_open = false;    // Flag: initialization succeeded, network device open (set by EtherInit())
  45.  
  46. uint32 ether_data = 0;    // Mac address of driver data in MacOS RAM
  47.  
  48.  
  49. /*
  50.  *  Driver Open() routine
  51.  */
  52.  
  53. int16 EtherOpen(uint32 pb, uint32 dce)
  54. {
  55.     D(bug("EtherOpen\n"));
  56.  
  57.     // Allocate driver data
  58.     M68kRegisters r;
  59.     r.d[0] = SIZEOF_etherdata;
  60.     Execute68kTrap(0xa71e, &r);        // NewPtrSysClear()
  61.     if (r.a[0] == 0)
  62.         return openErr;
  63.     ether_data = r.a[0];
  64.     D(bug(" data %08lx\n", ether_data));
  65.  
  66.     WriteMacInt16(ether_data + ed_DeferredTask + qType, dtQType);
  67.     WriteMacInt32(ether_data + ed_DeferredTask + dtAddr, ether_data + ed_Code);
  68.     WriteMacInt32(ether_data + ed_DeferredTask + dtParam, ether_data + ed_Result);
  69.                                                             // Deferred function for signalling that packet write is complete (pointer to mydtResult in a1)
  70.     WriteMacInt16(ether_data + ed_Code, 0x2019);            //  move.l    (a1)+,d0    (result)
  71.     WriteMacInt16(ether_data + ed_Code + 2, 0x2251);        //  move.l    (a1),a1        (dce)
  72.     WriteMacInt32(ether_data + ed_Code + 4, 0x207808fc);    //  move.l    JIODone,a0
  73.     WriteMacInt16(ether_data + ed_Code + 8, 0x4ed0);        //  jmp        (a0)
  74.  
  75.     WriteMacInt32(ether_data + ed_DCE, dce);
  76.                                                             // ReadPacket/ReadRest routines
  77.     WriteMacInt16(ether_data + ed_ReadPacket, 0x6010);        //    bra        2
  78.     WriteMacInt16(ether_data + ed_ReadPacket + 2, 0x3003);    //  move.w    d3,d0
  79.     WriteMacInt16(ether_data + ed_ReadPacket + 4, 0x9041);    //  sub.w    d1,d0
  80.     WriteMacInt16(ether_data + ed_ReadPacket + 6, 0x4a43);    //  tst.w    d3
  81.     WriteMacInt16(ether_data + ed_ReadPacket + 8, 0x6702);    //  beq        1
  82.     WriteMacInt16(ether_data + ed_ReadPacket + 10, M68K_EMUL_OP_ETHER_READ_PACKET);
  83.     WriteMacInt16(ether_data + ed_ReadPacket + 12, 0x3600);    //1 move.w    d0,d3
  84.     WriteMacInt16(ether_data + ed_ReadPacket + 14, 0x7000);    //  moveq    #0,d0
  85.     WriteMacInt16(ether_data + ed_ReadPacket + 16, 0x4e75);    //  rts
  86.     WriteMacInt16(ether_data + ed_ReadPacket + 18, M68K_EMUL_OP_ETHER_READ_PACKET);    //2
  87.     WriteMacInt16(ether_data + ed_ReadPacket + 20, 0x4a43);    //  tst.w    d3
  88.     WriteMacInt16(ether_data + ed_ReadPacket + 22, 0x4e75);    //  rts
  89.     return 0;
  90. }
  91.  
  92.  
  93. /*
  94.  *  Driver Control() routine
  95.  */
  96.  
  97. int16 EtherControl(uint32 pb, uint32 dce)
  98. {
  99.     uint16 code = ReadMacInt16(pb + csCode);
  100.     D(bug("EtherControl %d\n", code));
  101.     switch (code) {
  102.         case 1:        // KillIO
  103.             return -1;
  104.  
  105.         case kENetAddMulti:        // Add multicast address
  106.             D(bug("AddMulti %08lx%04x\n", ReadMacInt32(pb + eMultiAddr), ReadMacInt16(pb + eMultiAddr + 4)));
  107.             if (net_open)
  108.                 return ether_add_multicast(pb);
  109.             else
  110.                 return noErr;
  111.  
  112.         case kENetDelMulti:        // Delete multicast address
  113.             D(bug("DelMulti %08lx%04x\n", ReadMacInt32(pb + eMultiAddr), ReadMacInt16(pb + eMultiAddr + 4)));
  114.             if (net_open)
  115.                 return ether_del_multicast(pb);
  116.             else
  117.                 return noErr;
  118.  
  119.         case kENetAttachPH:        // Attach protocol handler
  120.             D(bug("AttachPH prot %04x, handler %08lx\n", ReadMacInt16(pb + eProtType), ReadMacInt32(pb + ePointer)));
  121.             if (net_open)
  122.                 return ether_attach_ph(ReadMacInt16(pb + eProtType), ReadMacInt32(pb + ePointer));
  123.             else
  124.                 return noErr;
  125.  
  126.         case kENetDetachPH:        // Detach protocol handler
  127.             D(bug("DetachPH prot %04x\n", ReadMacInt16(pb + eProtType)));
  128.             if (net_open)
  129.                 return ether_detach_ph(ReadMacInt16(pb + eProtType));
  130.             else
  131.                 return noErr;
  132.  
  133.         case kENetWrite:        // Transmit raw Ethernet packet
  134.             D(bug("EtherWrite\n"));
  135.             if (ReadMacInt16(ReadMacInt32(pb + ePointer)) < 14)
  136.                 return eLenErr;    // Header incomplete
  137.             if (net_open)
  138.                 return ether_write(ReadMacInt32(pb + ePointer));
  139.             else
  140.                 return noErr;
  141.  
  142.         case kENetGetInfo: {    // Get device information/statistics
  143.             D(bug("GetInfo buf %08lx, size %d\n", ReadMacInt32(pb + ePointer), ReadMacInt16(pb + eBuffSize)));
  144.  
  145.             // Collect info (only ethernet address)
  146.             uint8 buf[18];
  147.             memset(buf, 0, 18);
  148.             memcpy(buf, ether_addr, 6);
  149.  
  150.             // Transfer info to supplied buffer
  151.             int16 size = ReadMacInt16(pb + eBuffSize);
  152.             if (size > 18)
  153.                 size = 18;
  154.             WriteMacInt16(pb + eDataSize, size);    // Number of bytes actually written
  155.             Host2Mac_memcpy(ReadMacInt32(pb + ePointer), buf, size);
  156.             return noErr;
  157.         }
  158.  
  159.         case kENetSetGeneral:    // Set general mode (always in general mode)
  160.             D(bug("SetGeneral\n"));
  161.             return noErr;
  162.  
  163.         default:
  164.             printf("WARNING: Unknown EtherControl(%d)\n", code);
  165.             return controlErr;
  166.     }
  167. }
  168.  
  169.  
  170. /*
  171.  *  Ethernet ReadPacket routine
  172.  */
  173.  
  174. void EtherReadPacket(uint8 **src, uint32 &dest, uint32 &len, uint32 &remaining)
  175. {
  176.     D(bug("EtherReadPacket src %08lx, dest %08lx, len %08lx, remaining %08lx\n", *src, dest, len, remaining));
  177.     uint32 todo = len > remaining ? remaining : len;
  178.     Host2Mac_memcpy(dest, *src, todo);
  179.     *src += todo;
  180.     dest += todo;
  181.     len -= todo;
  182.     remaining -= todo;
  183. }
  184.